home *** CD-ROM | disk | FTP | other *** search
- ;; -*- Mode:LISP; Package:BOXER; Base:10.;fonts:cptfont; -*-
- ;;
- ;; Copyright 1984 Massachusetts Institute of Technology
- ;;
- ;; Permission to use, copy, modify, distribute, and sell this software
- ;; and its documentation for any purpose is hereby granted without fee,
- ;; provided that the above copyright notice appear in all copies and that
- ;; both that copyright notice and this permission notice appear in
- ;; supporting documentation, and that the name of M.I.T. not be used in
- ;; advertising or publicity pertaining to distribution of the software
- ;; without specific, written prior permission. M.I.T. makes no
- ;; representations about the suitability of this software for any
- ;; purpose. It is provided "as is" without express or implied warranty.
- ;;
- ;;
- ;; +-Data--+
- ;; This file is part of the | BOXER | system
- ;; +-------+
- ;;
- ;; Graphics Object Definitions
- ;; Coordinate Transformation and Drawing Utilities
- ;; Also mouse-sensitivity code.
-
- ;;; Each slot in the turlte flavor holds a dotted pair consisting of
- ;;; the value of the slot in lisp and the box which holds the value in Boxer
- ;;; All the turtle mutators keep these two things in synch. The second half
- ;;; dotted pair is nil if the sprite is missing a box for that state variable.
-
- (DEFFLAVOR TURTLE
- ((X-POSITION '(0.))
- (Y-POSITION '(0.))
- (ASSOC-GRAPHICS-BOX NIL)
- (SPRITE-BOX NIL)
- (SHOWN-P '(T))
- (PEN '(DOWN))
- (HOME '((0 0 )))
- (SUBSPRITES NIL)
- (SUPERIOR-TURTLE NIL)
- (HEADING (NCONS 0.))
- (SHAPE (NCONS *TURTLE-SHAPE*))
- (SIZE '(1.)))
- ()
- (:SETTABLE-INSTANCE-VARIABLES SPRITE-BOX SUPERIOR-TURTLE)
- (:GETTABLE-INSTANCE-VARIABLES ASSOC-GRAPHICS-BOX SPRITE-BOX SUBSPRITES)
- :INITABLE-INSTANCE-VARIABLES)
-
- (DEFMETHOD (TURTLE :DUMP-FORM) ()
- (LIST 'TURTLE :X-POSITION (NCONS (CAR X-POSITION)) :Y-POSITION (NCONS (CAR Y-POSITION))
- :SHOWN-P (NCONS (CAR SHOWN-P)) :PEN (NCONS (CAR PEN)) :HOME (NCONS (CAR HOME))
- :HEADING (NCONS (CAR HEADING)) :SHAPE (NCONS (CAR SHAPE)) :SIZE (NCONS (CAR SIZE))))
-
- (DEFUN MAKE-TURTLE ()
- (MAKE-INSTANCE 'TURTLE))
-
- (DEFMETHOD (TURTLE :SET-SPRITE-BOX) (BOX)
- (SETQ SPRITE-BOX BOX))
-
- (DEFMETHOD (TURTLE :COPY) ()
- (MAKE-INSTANCE 'TURTLE
- ':X-POSITION (NCONS (CAR X-POSITION))
- ':Y-POSITION (NCONS (CAR Y-POSITION))
- ':HEADING (NCONS (CAR HEADING))
- ':SHOWN-P (NCONS (CAR SHOWN-P))
- ':PEN (NCONS (CAR PEN))
- ':HOME (NCONS (CAR HOME))
- ':SHAPE (NCONS (CAR SHAPE))
- ':SIZE (NCONS (CAR SIZE))))
-
- (DEFTYPE-CHECKING-MACROS TURTLE "A Turtle")
-
- ;;; Some useful variables that various types of objects need
-
- (DEFCONST *DEFAULT-GRAPHICS-OBJECT-HEIGHT* 10.0)
-
- (DEFCONST *DEFAULT-GRAPHICS-OBJECT-WIDTH* 10.0)
-
-
- ;;; turtle shape
-
- (DEFCONST *TURTLE-HEIGHT* 15.0)
-
- (DEFCONST *TURTLE-HALF-BASE* 5.0)
-
- (DEFCONST *TURTLE-SHAPE*
- (LIST :UP 0 (* .333 *TURTLE-HEIGHT*) :DOWN
- (- *TURTLE-HALF-BASE*) 0
- *TURTLE-HALF-BASE* (- *TURTLE-HEIGHT*)
- *TURTLE-HALF-BASE* *TURTLE-HEIGHT*
- (- *TURTLE-HALF-BASE*) 0
- :UP 0 (- (* .333 *TURTLE-HEIGHT*))))
-
-
- ;;; Adding and removing graphics-objects to/from GRAPHICS-BOXES
-
- (DEFMETHOD (GRAPHICS-BOX :ADD-GRAPHICS-OBJECT) (NEW-OBJECT)
- (TELL NEW-OBJECT :SET-ASSOC-GRAPHICS-BOX SELF)
- (SETF (GRAPHICS-SHEET-OBJECT-LIST GRAPHICS-SHEET)
- (PUSH NEW-OBJECT (GRAPHICS-SHEET-OBJECT-LIST GRAPHICS-SHEET))))
-
- (DEFMETHOD (GRAPHICS-BOX :REMOVE-GRAPHICS-OBJECT) (OLD-OBJECT)
- (WHEN (EQ (TELL OLD-OBJECT :ASSOC-GRAPHICS-BOX) SELF)
- (TELL OLD-OBJECT :SET-ASSOC-GRAPHICS-BOX NIL)
- (SETF (GRAPHICS-SHEET-OBJECT-LIST GRAPHICS-SHEET)
- (DELQ OLD-OBJECT (GRAPHICS-SHEET-OBJECT-LIST GRAPHICS-SHEET)))))
-
- (DEFMETHOD (GRAPHICS-DATA-BOX :ADD-GRAPHICS-OBJECT) (NEW-OBJECT)
- (TELL NEW-OBJECT :SET-ASSOC-GRAPHICS-BOX SELF)
- (SETF (GRAPHICS-SHEET-OBJECT-LIST GRAPHICS-SHEET)
- (PUSH NEW-OBJECT (GRAPHICS-SHEET-OBJECT-LIST GRAPHICS-SHEET))))
-
- (DEFMETHOD (GRAPHICS-DATA-BOX :REMOVE-GRAPHICS-OBJECT) (OLD-OBJECT)
- (WHEN (EQ (TELL OLD-OBJECT :ASSOC-GRAPHICS-BOX) SELF)
- (TELL OLD-OBJECT :SET-ASSOC-GRAPHICS-BOX NIL)
- (SETF (GRAPHICS-SHEET-OBJECT-LIST GRAPHICS-SHEET)
- (DELQ OLD-OBJECT (GRAPHICS-SHEET-OBJECT-LIST GRAPHICS-SHEET)))))
-
-
- ;;; Mouse Sensitivity
-
- (DEFMETHOD (SPRITE-BLINKER :OFF) ()
- (TELL SELF :SET-VISIBILITY NIL)
- (SETQ SELECTED-SPRITE NIL))
-
- ;;; reset the sprite blinker after every change
- (DEFMETHOD (GRAPHICS-BOX :AFTER :MODIFIED) (IGNORE)
- (TELL *SPRITE-BLINKER* :OFF))
-
- ;;; this does the highlighting
- (DEFMETHOD (SCREEN-BOX :HIGHLIGHT-SPRITE-UNDER-MOUSE) (X Y)
- (LET ((G-BOX (IF (GRAPHICS-BOX? ACTUAL-OBJ)
- ACTUAL-OBJ
- (TELL ACTUAL-OBJ :PORTS))))
- (WITH-GRAPHICS-VARS-BOUND G-BOX
- (WITH-TURTLE-SLATE-ORIGINS SELF
- (LET ((USER-X (USER-COORDINATE-X (- X %ORIGIN-X-OFFSET)))
- (USER-Y (USER-COORDINATE-Y (- Y %ORIGIN-Y-OFFSET 1))))
- (LET ((SPRITE (FIND-SPRITE-UNDER-POINT
- USER-X USER-Y
- (GRAPHICS-SHEET-OBJECT-LIST GR-SHEET))))
- (IF (NULL SPRITE)
- (TELL *SPRITE-BLINKER* :OFF)
- (TELL *SPRITE-BLINKER* :HIGHLIGHT-SPRITE SPRITE SELF))))))))
-
- (DEFVAR *MOUSING-ALLOWABLE-ERROR* 5 "Allowed error when pointing to a sprite with the mouse")
-
- (DEFUN FIND-SPRITE-UNDER-POINT (USER-X USER-Y OBJECT-LIST
- &AUX SPRITE (SPRITE-AREA 999999)
- LEFT TOP RIGHT BOTTOM OBJECT-AREA OBJECT)
- (TAGBODY
- LOOP
- (SETQ OBJECT (CAR OBJECT-LIST))
- (SETQ OBJECT-LIST (CDR OBJECT-LIST))
- (WHEN (AND (TURTLE? OBJECT) (TELL OBJECT :ABSOLUTE-SHOWN-P))
- (MULTIPLE-VALUE (LEFT TOP RIGHT BOTTOM)
- (TELL OBJECT :ENCLOSING-RECTANGLE))
- (SETQ OBJECT-AREA (ABS (* (- LEFT RIGHT) (- TOP BOTTOM))))
- (WHEN (AND (< OBJECT-AREA SPRITE-AREA)
- (INCLUSIVE-BETWEEN? USER-X
- LEFT
- (+ RIGHT *MOUSING-ALLOWABLE-ERROR*))
- (INCLUSIVE-BETWEEN? USER-Y
- (- BOTTOM *MOUSING-ALLOWABLE-ERROR*)
- TOP)
- (SETQ SPRITE-AREA OBJECT-AREA SPRITE OBJECT)))
- (SETQ OBJECT-LIST (APPEND OBJECT-LIST (TELL OBJECT :SUBSPRITES))))
- (WHEN OBJECT-LIST (GO LOOP)))
- SPRITE)
-
- ;;; call this method only within WITH-TURTLE-SLATE-ORIGINS.
-
- (DEFMETHOD (SPRITE-BLINKER :HIGHLIGHT-SPRITE) (SPRITE SCREEN-BOX)
- (MULTIPLE-VALUE-BIND (LEFT TOP RIGHT BOTTOM)
- (TELL SPRITE :ENCLOSING-RECTANGLE)
- (LET ((ARRAY-LEFT (MAX (FIX-ARRAY-COORDINATE-X LEFT) -1.))
- (ARRAY-TOP (MAX (FIX-ARRAY-COORDINATE-Y TOP) -1.))
- (ARRAY-RIGHT (MIN (FIX-ARRAY-COORDINATE-X RIGHT) (1+ %DRAWING-WIDTH)))
- (ARRAY-BOTTOM (MIN (FIX-ARRAY-COORDINATE-Y BOTTOM) (1+ %DRAWING-HEIGHT))))
- (LET ((X (+ -2. %ORIGIN-X-OFFSET ARRAY-LEFT))
- (Y (+ -2. %ORIGIN-Y-OFFSET ARRAY-TOP))
- (WIDTH (- ARRAY-RIGHT ARRAY-LEFT -2.))
- (HEIGHT (- ARRAY-BOTTOM ARRAY-TOP -2.)))
- (TELL SELF :SET-CURSORPOS X Y )
- (TELL SELF :SET-SIZE WIDTH HEIGHT)
- (TELL SELF :SET-VISIBILITY T))))
- (SETQ SELECTED-SPRITE SPRITE)
- (SETQ SPRITE-SCREEN-BOX SCREEN-BOX))
-
-
- ;;; coordinate transformations.
- ;;;
- ;;; ARRAY coordinates are referenced to the indices of the bit-array of the graphics box
- ;;; therefore in ARRAY coordinates, (0, 0) is in the upper-left hand corner whereas...
- ;;; ...in USER coordinates, which refer to the coordinates in which the user talks to the
- ;;; object, (0, 0) will be more or less in the middle of the box.
- ;;;
-
- ;;; USER ARRAY
-
- (DEFUN FIX-ARRAY-COORDINATE-X (USER-X)
- (FIXR (ARRAY-COORDINATE-X USER-X)))
-
- (DEFUN ARRAY-COORDINATE-X (USER-X)
- (+ (// %DRAWING-WIDTH 2) USER-X))
-
- (DEFUN FIX-ARRAY-COORDINATE-Y (USER-Y)
- (FIXR (ARRAY-COORDINATE-Y USER-Y)))
-
- (DEFUN ARRAY-COORDINATE-Y (USER-Y)
- (- (// %DRAWING-HEIGHT 2) (* USER-Y *SCRUNCH-FACTOR*)))
-
- ;;; ARRAY USER
-
- (DEFUN USER-COORDINATE-X (ARRAY-X)
- (- ARRAY-X (// %DRAWING-WIDTH 2)))
-
- (DEFUN USER-COORDINATE-Y (ARRAY-Y)
- (// (- (// %DRAWING-HEIGHT 2) ARRAY-Y) *SCRUNCH-FACTOR*))
-
- ;;; these want ARRAY coordinates
-
- (DEFUN POINT-IN-ARRAY? (X Y)
- (AND (X-IN-ARRAY? X)
- (Y-IN-ARRAY? Y)))
-
- (DEFUN X-IN-ARRAY? (X)
- (AND ( X 0) (< X %DRAWING-WIDTH)))
-
- (DEFUN Y-IN-ARRAY? (Y)
- (AND ( Y 0) (< Y %DRAWING-HEIGHT)))
-
-
-
- ;;; normalize coordinates to the on screen position
-
- (DEFUN WRAP-OBJECT-COORDS (OBJECT)
- (TELL OBJECT :SET-X-POSITION (WRAP-X-COORDINATE (TELL OBJECT :X-POSITION)))
- (TELL OBJECT :SET-Y-POSITION (WRAP-Y-COORDINATE (TELL OBJECT :Y-POSITION))))
-
- (DEFUN WRAP-X-COORDINATE (USER-X)
- (USER-COORDINATE-X (FLOAT-MODULO (ARRAY-COORDINATE-X USER-X) %DRAWING-WIDTH)))
-
- (DEFUN WRAP-Y-COORDINATE (USER-Y)
- (USER-COORDINATE-Y (FLOAT-MODULO (ARRAY-COORDINATE-Y USER-Y) %DRAWING-HEIGHT)))
-
- (DEFUN FLOAT-MODULO (NUM MOD)
- (LET ((X (- NUM (* (FIX (// NUM MOD)) MOD))))
- (IF (MINUSP X) (+ X MOD) X)))
-
- ;;; ******************************************************************
- ;;; Everything after this line has been made obsolete by sprite boxes.
- ;;; and is only here for reference.
- ;;; ******************************************************************
-
- ;;; Here is the basic flavor
- ;;; This defines a graphics object by its location only. Anything built out of this should
- ;;; define its own methods for saving (in files) and displaying
- ;(DEFFLAVOR MINIMUM-GRAPHICS-OBJECT
- ; ((X-POSITION 0.)
- ; (Y-POSITION 0.)
- ; (assoc-graphics-box NIL))
- ; ()
- ; :GETTABLE-INSTANCE-VARIABLES
- ; :SETTABLE-INSTANCE-VARIABLES
- ; :INITABLE-INSTANCE-VARIABLES
- ; (:REQUIRED-METHODS :DRAW :ERASE)
- ; (:DOCUMENTATION :ESSENTIAL-MIXIN
- ; "All other graphics objects are built on top of this flavor. "))
-
- (DEFTYPE-CHECKING-MACROS GRAPHICS-OBJECT "A graphics object")
-
- ;;; some useful MIXINS
- ;(DEFFLAVOR EXPORTING-NAME-MIXIN
- ; ((NAME NIL))
- ; ()
- ; :GETTABLE-INSTANCE-VARIABLES
- ; :INITABLE-INSTANCE-VARIABLES
- ; (:REQUIRED-FLAVORS MINIMUM-GRAPHICS-OBJECT)
- ; (:DOCUMENTATION :MIXIN
- ; "Gives the object a name so it can be accessed from outside of the Graphics Box. "))
-
- ;;; BASIC methods that EVERY ONE uses
- ;;; higher level object generally should define their own main method for the following
- ;;; made obsolete by sprite boxes
- ;(DEFMETHOD (MINIMUM-GRAPHICS-OBJECT :GRAPHICS-BOX) ()
- ; (GRAPHICS-SHEET-SUPERIOR-BOX ASSOCIATED-SHEET))
- ;
- ;(DEFMETHOD (MINIMUM-GRAPHICS-OBJECT :BEFORE :SET-ASSOCIATED-SHEET) (NEW-SHEET)
- ; (WHEN (AND (NEQ NEW-SHEET ASSOCIATED-SHEET) (NOT-NULL ASSOCIATED-SHEET))
- ; (TELL SELF :ERASE)))
- ;
- ;(DEFMETHOD (MINIMUM-GRAPHICS-OBJECT :AFTER :SET-ASSOCIATED-SHEET) (NEW-SHEET)
- ; (WHEN (NOT-NULL NEW-SHEET)
- ; (TELL SELF :DRAW)))
- ;
- ;(DEFMETHOD (MINIMUM-GRAPHICS-OBJECT :DESCRIPTION-LIST) ()
- ; "This method should return a list of lists suitable for MAKE-BOX"
- ; (LIST (NCONS (FORMAT NIL "I am a ~A" (TYPEP SELF)))
- ; (NCONS (FORMAT NIL "X-position ~D" X-POSITION))
- ; (NCONS (FORMAT NIL "Y-Position ~D" Y-POSITION))))
- ;
- ;(DEFMETHOD (MINIMUM-GRAPHICS-OBJECT :DRAW) ()
- ; "This draw method assumes that position (0, 0) is in the upper left hand corner.
- ;Higher level draw methods which want (0, 0) to be elsewhere (like the
- ; middle) should
- ;convert x and y positions before calling DRAW-LINE. "
- ; (WITH-GRAPHICS-VARS-BOUND (GRAPHICS-SHEET-SUPERIOR-BOX ASSOCIATED-SHEET)
- ; (CK-MODE-DRAW-LINE X-POSITION Y-POSITION (+ X-POSITION *DEFAULT-GRAPHICS-OBJECT-WIDTH*)
- ; (+ Y-POSITION *DEFAULT-GRAPHICS-OBJECT-HEIGHT*))
- ; (CK-Mode-DRAW-LINE (+ X-POSITION *DEFAULT-GRAPHICS-OBJECT-WIDTH*) Y-POSITION
- ; X-POSITION (+ Y-POSITION *DEFAULT-GRAPHICS-OBJECT-HEIGHT*))))
- ;
- ;(DEFMETHOD (MINIMUM-GRAPHICS-OBJECT :ERASE) ()
- ; (TELL SELF :DRAW))
- ;
-
-
-
- ;;; Methods for MIXINs
- ;;; a crock so that TELL will work
- ;(DEFMETHOD (EXPORTING-NAME-MIXIN :LOOKUP-STATIC-VARIABLE-CHECK-SUPERIORS) (VAR)
- ; (TELL-CHECK-NIL (GRAPHICS-SHEET-SUPERIOR-BOX ASSOCIATED-SHEET)
- ; :LOOKUP-STATIC-VARIABLE-CHECK-SUPERIORS VAR))
- ;
- ;(DEFMETHOD (EXPORTING-NAME-MIXIN :BEFORE :SET-ASSOCIATED-SHEET) (NEW-SHEET)
- ; (COND ((AND (NULL NEW-SHEET) (NOT-NULL ASSOCIATED-SHEET))
- ; (TELL (GRAPHICS-SHEET-SUPERIOR-BOX ASSOCIATED-SHEET)
- ; :REMOVE-ALL-STATIC-BINDINGS SELF))
- ; ((AND (NEQ NEW-SHEET ASSOCIATED-SHEET)(NOT-NULL NEW-SHEET)(NOT-NULL ASSOCIATED-SHEET))
- ; (LET ((SURROUNDING-BOX (GRAPHICS-SHEET-SUPERIOR-BOX NEW-SHEET)))
- ; (TELL (GRAPHICS-SHEET-SUPERIOR-BOX ASSOCIATED-SHEET)
- ; :REMOVE-ALL-STATIC-BINDINGS SELF)
- ; (WHEN (AND NAME (SYMBOLP NAME))
- ; (TELL SURROUNDING-BOX :ADD-STATIC-VARIABLE-PAIR NAME SELF)
- ; (TELL SURROUNDING-BOX :EXPORT-VARIABLE NAME))))))
- ;
-
-